﻿// ===============================================================================
// Project Name        :    Gfw.Repositories.Admin
// Project Description :    
// ===============================================================================
// Class Name          :    UsrUserRepository
// Namespace:          :    Gfw.Repositories.Admin
// Class Version       :    v1.0.0.0
// Class Description   :    
// CLR Version:        :    4.0.30319.17626
//Author               :    lif
// Machine             :    ADICO-PC
// Create Time         :    2012/6/24 15:05:37
// Update Time         :    2012/6/24 15:05:37
// ===============================================================================
// Copyright © lif 2012 . All rights reserved.
// ===============================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Gfw.Models.Admin;
using Gfw.Repositories.Admin.ViewModels;
using Gfw.Repository;
using L.Basic.Authority.Models;
using NHibernate;
using NHibernate.Criterion;

namespace Gfw.Repositories.Admin
{
    public class UsrUserRepository : Repository<UsrUser>
    {

        #region Const Fields

        private const string DEFAULT_PASSWORD = "123";

        #endregion

        #region 基础操作部分
        public UsrUser GetUserByLoginName(string loginName)
        {
            var query = Session.CreateQuery(
                @"from UsrUser  as u  where u.LoginName=:loginName")
                .SetString("loginName", loginName);
            var user = query.List<UsrUser>().FirstOrDefault();


            return user;
        }

        /// <summary>
        /// 根据入会的序号查询会员
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public UsrUser GetUserByUserIndex(int index)
        {
            var query = Session.CreateQuery(
               @"from UsrUser  as u  where u.UserIndex=:index")
               .SetInt32("index", index);
            var user = query.List<UsrUser>().FirstOrDefault();


            return user;
        }

        public UsrUser GetUserByCodeNumber(Int64 codeNumber)
        {
            var query = Session.CreateQuery(
              @"from UsrUser  as u  where u.CodeNumber=:codeNumber")
              .SetInt64("codeNumber", codeNumber);
            var user = query.List<UsrUser>().FirstOrDefault();


            return user;
        }

        /// <summary>
        /// 获取该会员所有被推荐的会员
        /// </summary>
        /// <param name="recommenderID">推荐人ID</param>
        /// <param name="pageIndex">base on 0</param>
        /// <param name="pageSize"></param>
        /// <param name="pageTotal"></param>
        /// <returns></returns>
        public IList<UsrUser> GetUserRecommendMembersInfo(string recommenderID, int pageIndex, int pageSize, out int pageTotal)
        {
            int total = (int)Session.CreateQuery("select count(*) from UsrUser where Recommender=:userID")
                .SetString("userID", recommenderID).UniqueResult<long>();
            pageTotal = (total + pageSize - 1) / pageSize;

            var query = Session.CreateQuery(
                @"from UsrUser as u where u.Recommender=:userID")
                .SetString("userID", recommenderID).SetFirstResult(pageIndex * pageSize).SetMaxResults(pageSize);

            return query.List<UsrUser>();
        }

        /// <summary>
        /// 统计左右孩子总计
        /// </summary>
        /// <param name="recommenderID">推荐人ID</param>
        /// <param name="recommenderCode">推荐人Code</param>
        /// <param name="leftChildrenCount">左总计</param>
        /// <param name="rightChildrenCount">右总计</param>
        public void GetRecommendMembersCount(string recommenderID, string recommenderCode,out long leftChildrenCount, out long rightChildrenCount)
        {
            if (string.IsNullOrEmpty(recommenderID) || string.IsNullOrEmpty(recommenderCode))
            {
                leftChildrenCount = 0;
                rightChildrenCount = 0;
                return;
            }

            string leftCode = recommenderCode + "0%", rightCode = recommenderCode + "1%";

            leftChildrenCount = (long)Session.CreateQuery("select count(*) from UsrUser where Recommender=:userID" +
                             " and Code like :Code").SetString("userID", recommenderID).SetString("Code", leftCode)
                             .UniqueResult<long>();

            rightChildrenCount = (long)Session.CreateQuery("select count(*) from UsrUser where Recommender=:userID" +
                             " and Code like :Code").SetString("userID", recommenderID).SetString("Code", rightCode)
                             .UniqueResult<long>();
        }

        /// <summary>
        /// 根据code代码获取用户信息
        /// </summary>
        /// <param name="code">code</param>
        /// <returns></returns>
        public UsrUser GetUserByCode(string code)
        {
            var query = Session.CreateQuery(
              @"from UsrUser  as u  where u.Code=:code")
              .SetString("code", code);
            var user = query.List<UsrUser>().FirstOrDefault();


            return user;
        }

        #endregion

        #region 二叉树判断部分

        /// <summary>
        /// 判断当前用户是否具有兄弟节点。时间戳：查询用户注册时间点的状态
        /// </summary>
        /// <param name="user">查找用兄弟用户的帐户</param>
        /// <param name="useTimestamp">是否使用时间戳标识</param>
        /// <returns></returns>
        public virtual bool HasBrother(UsrUser user, bool useTimestamp, UnitOfWork unitOfWork = null)
        {
            //如果当前用户节点是根节点
            if (user.Code.Length <= 1)
                return false;

            string parentCode = user.Code.Substring(0, user.Code.Length - 1);
            string brotherCode = user.Code.Last() == '0' ? parentCode + "1" : parentCode + "0";

            ISession session = unitOfWork == null ? Session : unitOfWork.Session;

            var query = session.CreateQuery(
                @"select count(*) from UsrUser  where Code=:Code and RegistrationDate<:RegistrationDate")
                .SetString("Code", brotherCode)
                .SetDateTime("RegistrationDate", useTimestamp ? user.RegistrationDate.Value : DateTime.MaxValue);
            return query.UniqueResult<long>() > 0;

        }


        /// <summary>
        /// 判断当前用户的祖父是否具有4个数字
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public virtual bool HasFullCousin(UsrUser user, bool useTimestamp, UnitOfWork unitOfWork = null)
        {
            //判断逻辑，只需要4个code长度与当前用户相同的用户。
            string grandCode = user.Code.Substring(0, user.Code.Length - 1);
            ISession session = unitOfWork == null ? Session : unitOfWork.Session;

            var query = session.CreateQuery(
                @"select count(*) from UsrUser  where Code like :Code and RegistrationDate<:RegistrationDate")
                .SetString("Code", grandCode + "__")
                .SetDateTime("RegistrationDate", useTimestamp ? user.RegistrationDate.Value : DateTime.MaxValue);
            return query.UniqueResult<long>() == 4;
        }

        /// <summary>
        /// 获取当前用的父亲节点
        /// </summary>
        /// <param name="user"></param>
        /// <param name="unitOfWork"></param>
        /// <returns></returns>
        public virtual UsrUser GetParent(UsrUser user, UnitOfWork unitOfWork = null)
        {
            return Get(user.Parentid, unitOfWork);
        }

        #endregion

        #region 用户认证部分
        /// <summary>
        /// 验证用户信息，并获取用户信息，包括部门和角色
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="password"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public bool Validate(string loginName, string password, out User user)
        {
            user = null;
            var query = Session.CreateQuery(@"from UsrUser as u 
                where u.LoginName=:loginName and u.Password=:password and u.IsLock=0")
                .SetString("loginName", loginName)
                .SetString("password", password);
            var users = query.List<UsrUser>();
            if (users.Count == 1)
            {
                var lpfuser = users.First();
                user = new User
                {
                    Id = lpfuser.Id,
                    LoginName = lpfuser.LoginName,
                    Name = lpfuser.Name,
                    Password = lpfuser.Password,
                    State = UserState.Normal,
                    Code = lpfuser.Code,
                    Tag = lpfuser,
                    Roles = new List<Role>()
                };
                user.Roles.Add(new Role() { Id = "RUser", Name = "RUser" });
                return true;

            }
            return false;
        }
        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="oldPassword"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public bool ChangePassword(string loginName, string oldPassword, string newPassword)
        {
            var query = Session.CreateQuery(@"from UsrUser as u 
                where u.LoginName=:loginName and u.Password=:oldPassword")
              .SetString("loginName", loginName)
              .SetString("oldPassword", oldPassword);
            var user = query.List<UsrUser>().FirstOrDefault();
            if (user != null)
            {
                user.Password = newPassword;
                Update(user);
                return true;
            }
            return false;
        }


        /// <summary>
        /// 修改用户二级密码
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="password">登陆密码</param>
        /// <param name="oldSecondPassword"></param>
        /// <param name="newSecondPassword"></param>
        /// <returns></returns>
        public bool ChangeSecondPassword(string loginName, string password,
            string oldSecondPassword, string newSecondPassword)
        {
            IQuery query = null;

            if (string.IsNullOrEmpty(oldSecondPassword))
                query = Session.CreateQuery(@"from UsrUser as u 
                    where u.LoginName=:loginName and u.Password=:password 
                    and u.SecondPassword is null").SetString("loginName", loginName)
                    .SetString("password", password);
            else
                query = Session.CreateQuery(@"from UsrUser as u 
                    where u.LoginName=:loginName and u.Password=:password 
                    and u.SecondPassword=:oldSecondPassword").SetString("loginName", loginName)
                    .SetString("password", password).SetString("oldSecondPassword", oldSecondPassword);

            if (query == null)
                return false;

            var user = query.List<UsrUser>().FirstOrDefault();
            if (user != null)
            {
                user.SecondPassword = newSecondPassword;
                base.Update(user);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 二级密码验证部分
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="password"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public bool SecondValidate(string loginName, string password2)
        {

            var query = Session.CreateQuery(@"select count(*)  from UsrUser
                where LoginName=:loginName and SecondPassword=:password2")
                .SetString("loginName", loginName)
                .SetString("password2", password2);
            var result = query.UniqueResult<long>();
            if (result == 1)
            {
                return true;
            }
            return false;
        }
        

        #region 重置操作

        /// <summary>
        /// 重置登录密码
        /// </summary>
        /// <param name="loginName"></param>
        /// <returns></returns>
        public bool ResetLoginPassword(string loginName)
        {
            var query = Session.CreateQuery(@"from UsrUser as u
                where u.LoginName=:loginName")
                .SetString("loginName", loginName);
            var user = query.List<UsrUser>().FirstOrDefault();
            if (user != null)
            {
                user.Password = EncryptAlgorithmHelper.Encrypt(DEFAULT_PASSWORD, loginName);
                Update(user);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 重置二级密码
        /// </summary>
        /// <param name="loginName"></param>
        /// <returns></returns>
        public bool ResetSecondPassword(string loginName)
        {
            var query = Session.CreateQuery(@"from UsrUser as u
                where u.LoginName=:loginName")
                .SetString("loginName", loginName);
            var user = query.List<UsrUser>().FirstOrDefault();
            if (user != null)
            {
                user.SecondPassword= EncryptAlgorithmHelper.Encrypt(DEFAULT_PASSWORD, loginName);
                Update(user);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 重置密保问题
        /// </summary>
        /// <param name="loginName"></param>
        /// <returns></returns>
        public bool ResetSecurityQuestion(string loginName)
        {
            var query = Session.CreateQuery(@"from UsrUser as u
                where u.LoginName=:loginName")
                .SetString("loginName", loginName);
            var user = query.List<UsrUser>().FirstOrDefault();
            if (user != null)
            {
                user.Question1 = string.Empty;
                user.Question2 = string.Empty;
                user.Question3 = string.Empty;
                user.Answer1 = string.Empty;
                user.Answer2 = string.Empty;
                user.Answer3 = string.Empty;

                Update(user);
                return true;
            }
            return false;
        }

        #endregion

        #endregion

        #region 用户注册前的审查重复性

        /// <summary>
        /// 用户注册前的核查，包括用户名不能重复等
        /// </summary>
        /// <param name="loginName"></param>
        /// <returns></returns>
        public bool UniqueCheck(string loginName, string parentId, int parentArea)
        {
            var query = Session.CreateQuery(
                @"select count(*) from UsrUser as u 
                where u.LoginName=:loginName or (Parentid=:parentId and ParentArea=:parentArea)")
                .SetString("loginName", loginName)
                .SetInt32("parentArea", parentArea)
                .SetString("parentId", parentId);
            return query.UniqueResult<long>() == 0;
        }

        /// <summary>
        /// 身份证检查，只能用一次
        /// </summary>
        /// <param name="loginName">登录名</param>
        /// <param name="idCard"></param>
        /// <returns></returns>
        public bool UniqueCheckIDCard(string loginName, string idCard)
        {
            var query = Session.CreateQuery(
                @"select count(*) from UsrUser as u 
                where u.IdCard=:idCard and u.LoginName<>:loginName")
                .SetString("idCard", idCard)
                .SetString("loginName", loginName);
            return query.UniqueResult<long>() == 0;
        }

        #endregion

        #region 系谱图部分


        /// <summary>
        ///获取指定用户的最大孩子节点
        /// </summary>
        /// <param name="userCode"></param>
        /// <returns></returns>
        public UsrUser GetMaxCodeUser(string userCode)
        {
            var query = Session.CreateQuery(
               @"from UsrUser as u  where u.Code like :Code order by u.CodeNumber desc")
               .SetString("Code", string.Format("{0}%", userCode))
               .SetMaxResults(1);
            return query.UniqueResult<UsrUser>();
        }


        public IList<UsrUser> QueryChildrenRang(string userCode, Int64 minChildNumber, Int64 maxChildNumber)
        {
            var query = Session.CreateQuery(
                @"from UsrUser as u where u.Code like :userCode and u.CodeNumber>=:minChildNumber and u.CodeNumber<:maxChildNumber")
                .SetString("userCode", string.Format("{0}%", userCode))
                .SetInt64("minChildNumber", minChildNumber)
                .SetInt64("maxChildNumber", maxChildNumber);
            return query.List<UsrUser>();
        }

        public void QueryChildrenCount(string code, out int leftChildren, out int rightChildren)
        {
            var leftQuery = Session.CreateQuery(@"select count(*) from UsrUser as u where u.Code like:leftCode")
                .SetString("leftCode", string.Format("{0}0%", code))
                .UniqueResult<long>();
            var rightQuery = Session.CreateQuery(@"select count(*) from UsrUser as u where u.Code like:rightCode")
                .SetString("rightCode", string.Format("{0}1%", code))
                .UniqueResult<long>();
            leftChildren = (int)leftQuery;
            rightChildren = (int)rightQuery;
        }
        #endregion
    }
}
